/*
 * @Description: 登录相关类
 * @Author: chenju
 * @Date: 2022-05-18 15:04:25
 * @LastEditors: chenju
 * @LastEditTime: 2022-12-14 16:38:13
 */
import {
  userAccountLogin,
  supplierLogin,
  jwtLogin,
  geelyLogin,
  feishuLogin,
  dingtalkLogin,
  oaLoginApi
} from '@/apis/user/user'
import type { AccountLoginParams } from '@/apis/user/model/userModel'
import type { IUserType } from '@/store/modules/user/state'
import { store } from '@/store'
import { UserMutationTypes } from '@/store/modules/user/mutation-types'
import { useCustomRouter } from '@/hooks/useCustomRouter'
import type { LocationQuery } from 'vue-router'
import { getLocationOrigin } from '@/utils'
import { useRouterSubApp } from '@/commonModule/hooks/useRouterSubApp'

// 有效的url登录参数
export type UrlTokenParamsType =
  | { id_token: string }
  | { epssession: string }
  | { code: string }
  | { authCode: string }
  | { token: string }
  | { ticket: string }

interface LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  logoUrl?: null | string
  handleLogin: Fn
  handleLogout: Fn
}

const router = useCustomRouter()

const { routerToCoLogin } = useRouterSubApp()

// 用户中心类
export class GeelyLogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    this.userType = 'GEELY'
    this.logoutUrl = null
  }
  handleLogin(userInfo: { id_token: string }) {
    store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, false)
    return geelyLogin(userInfo.id_token)
  }
  handleLogout(noPermission = false) {
    console.log('GeelyLogin handleLogout', noPermission)
    // 如果没有权限
    // if (noPermission) {
    //   // 跳转no-permission
    //   router.replace('/no-permission');
    //   return false;
    // }
    window.location.href = import.meta.env.VUE_APP_GEELY_LOGOUT_URL + `${getLocationOrigin()}/pcf`
    return false
  }
}

// oa登录

export class OALogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    this.userType = 'OA'
    this.logoutUrl = null // todo:退出登录地址
    // this.logoutUrl = import.meta.env.VUE_APP_EPS_LOGIN_URL!;
  }
  handleLogin(userInfo: { ticket: string }) {
    store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, false)
    return oaLoginApi(userInfo.ticket)
  }
  handleLogout(noPermission = false) {
    window.location.href = window.location.origin + '/login'
    return false
  }
}

// SSO 之前从客户端登录

export class SSOLogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    this.userType = 'SSO'
    this.logoutUrl = null // todo:退出登录地址
    // this.logoutUrl = import.meta.env.VUE_APP_EPS_LOGIN_URL!;
  }
  handleLogin(userInfo: { ticket: string }) {
    return oaLoginApi(userInfo.ticket)
  }
  handleLogout() {
    window.location.href = window.location.origin + '/login'
    return false
  }
}

// jwt登录

export class JwtLogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    this.userType = 'JWT'
    this.logoutUrl = null
    // this.logoutUrl = import.meta.env.VUE_APP_EPS_LOGIN_URL!;
  }
  handleLogin(userInfo: { token: string }) {
    store.commit(UserMutationTypes.SET_USER_TYPE, this.userType)
    store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, true)
    return jwtLogin(userInfo.token)
  }
  handleLogout() {
    if (store.state.user.isJwtTokenLoginFlag) {
      store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, false)
      window.location.href = window.SUPPLIER_LOGOUT_URL
      return
    } else {
      routerToCoLogin()
      return
    }
  }
}

// 普通类
export class CarbonLogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    this.userType = 'CARBON'
    this.logoutUrl = null
  }
  handleLogin(userInfo: AccountLoginParams) {
    const userInfoData = {
      username: userInfo.username,
      password: userInfo.password,
      protocolFlag: userInfo.protocolFlag
    }
    const userInfoParams = {
      code: userInfo.code,
      randomStr: userInfo.randomStr
    }
    store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, false)
    return userAccountLogin(userInfoData, userInfoParams)
  }
  handleLogout() {
    window.location.href = window.location.origin + '/login'

    // routerToCoLogin();
    return false
  }
}

// 飞书登录
export class FeishuLogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    this.userType = 'FEISHU'
    this.logoutUrl = null
  }
  handleLogin(userInfo: { code: string }) {
    store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, false)
    return feishuLogin(userInfo.code)
  }
  handleLogout(noPermission = false) {
    console.log('FeishuLogin handleLogout', noPermission)
    // 如果没有权限
    // if (noPermission) {
    //   // 跳转no-permission
    //   router.replace('/no-permission');
    //   return false;
    // }
    routerToCoLogin()
    window.location.href = window.location.origin + '/login'
    return false
  }
}

// 飞书登录
export class DingtalkLogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    this.userType = 'DINGTALK'
    this.logoutUrl = null
  }
  handleLogin(userInfo: { authCode: string }) {
    store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, false)
    return dingtalkLogin(userInfo.authCode)
  }
  handleLogout(noPermission = false) {
    console.log('FeishuLogin handleLogout', noPermission)
    // 如果没有权限
    // if (noPermission) {
    //   // 跳转no-permission
    //   router.replace('/no-permissiZon');
    //   return false;
    // }
    window.location.href = window.location.origin + '/login'
    return false
  }
}

// 经销商端登录
export class SupplierLogin implements LoginBaseType {
  userType: IUserType
  logoutUrl: null | string
  constructor() {
    console.log('SupplierLogin')
    this.userType = 'SUPPLIER'
    this.logoutUrl = null
  }
  handleLogin(userInfo: AccountLoginParams) {
    const userInfoData = {
      username: userInfo.username,
      password: userInfo.password,
      protocolFlag: userInfo.protocolFlag
    }
    const userInfoParams = {
      code: userInfo.code,
      randomStr: userInfo.randomStr
    }
    store.commit(UserMutationTypes.SET_USER_TYPE, this.userType)
    store.commit(UserMutationTypes.SET_JWT_TOKEN_LOGIN_FLAG, false)
    return supplierLogin(userInfoData, userInfoParams)
  }
  handleLogout() {
    routerToCoLogin()
    return false
  }
}

/**
 * 登录方式：账号密码 ｜ sso
 */
export type LoginType = 'PWD' | 'SSO'

/**
 * 登录源：后台 ｜ 经销商端
 */
export type LoginSource = 'ADMIN' | 'SUPPLIER'

// 登录工厂
// NOTE 简单工厂
export class LoginFactory {
  // 登录操作
  static handleLogin(
    userInfo: AccountLoginParams | UrlTokenParamsType,
    loginType: LoginType,
    loginSource: LoginSource
  ) {
    console.log('loginSource', loginSource)
    if (loginSource === 'SUPPLIER') {
      if ('token' in userInfo) {
        return new JwtLogin().handleLogin(userInfo)
      }
      return new SupplierLogin().handleLogin(userInfo as AccountLoginParams)
    }
    if (loginType === 'SSO') {
      if ('id_token' in userInfo) {
        return new GeelyLogin().handleLogin(userInfo)
      } else if ('code' in userInfo) {
        return new FeishuLogin().handleLogin(userInfo)
      } else if ('authCode' in userInfo) {
        return new DingtalkLogin().handleLogin(userInfo)
      } else if ('ticket' in userInfo) {
        return new OALogin().handleLogin(userInfo)
      }
    }
    return new CarbonLogin().handleLogin(userInfo as AccountLoginParams)
  }

  // 根据userType获取类实例
  static GetInstanceByUserType(userType: IUserType) {
    console.log('GetInstanceByUserType', userType)
    if (userType === 'GEELY') {
      return new GeelyLogin()
    } else if (userType === 'FEISHU') {
      return new FeishuLogin()
    } else if (userType === 'DINGTALK') {
      return new DingtalkLogin()
    } else if (userType === 'SUPPLIER') {
      return new SupplierLogin()
    } else if (userType === 'JWT') {
      return new JwtLogin()
    } else if (userType === 'OA') {
      return new OALogin()
    } else {
      return new CarbonLogin()
    }
  }

  // 根据url上的参数获取类实例
  static GetInstanceByLocationQuery(locationQuery: LocationQuery) {
    if ('id_token' in locationQuery) {
      return new GeelyLogin()
    } else if ('code' in locationQuery) {
      return new FeishuLogin()
    } else if ('authCode' in locationQuery) {
      return new DingtalkLogin()
    } else if ('token' in locationQuery) {
      return new JwtLogin()
    } else if ('ticket' in locationQuery) {
      return new OALogin()
    } else if ('platform' in locationQuery && !locationQuery?.ticket) {
      return new SSOLogin()
    }
    return null
  }
}
